/*
 * Tic-Tac-Toe - Turn-based strategy game
 * Copyright 2008, 2009 Shayne Riley and Paul Maseberg
 *
 * Tic-Tac-Toe is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Tic-Tac-Toe is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Tic-Tac-Toe.  If not, see <http://www.gnu.org/licenses/>
 * or write to the Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * To contact the authors on questions or issues regarding the license,
 * you may send an email to <shayner at gmail dot com>
 */

#include "Audio.h"
#include <iostream>

using namespace std;

Audio::Audio()
{
    if(SDL_Init(SDL_INIT_AUDIO) != 0)
    {
        cerr << "Error: " << SDL_GetError() << endl;
        return; // TODO Is this a good idea? Returning like this in a ctor?
    }

    // Initialize the mixer.
    if(Mix_OpenAudio(
            AUDIO_RATE, AUDIO_FORMAT, AUDIO_CHANNELS, AUDIO_BUFFER_SIZE) != 0)
    {
        cerr << "SDL_mixer not initialized. Error: " << Mix_GetError() << endl;
        return; // TODO Is this a good idea? Returning like this in a ctor?
    }

    /// @todo change "res/" to a variable
    load("res/x.ogg", Audio::CLIP_X);
    load("res/o.ogg", Audio::CLIP_O);
    load("res/title.ogg", Audio::SONG_TITLE);
    load("res/win.ogg", Audio::SONG_WIN);
    load("res/lose.ogg", Audio::SONG_LOSE);
    load("res/draw.ogg", Audio::SONG_CAT);
    load("res/chad.ogg", Audio::SONG_SECRET);
}

Audio::~Audio()
{
    unload(Audio::CLIP_X);
    unload(Audio::CLIP_O);
    unload(Audio::SONG_TITLE);
    unload(Audio::SONG_WIN);
    unload(Audio::SONG_LOSE);
    unload(Audio::SONG_CAT);
    unload(Audio::SONG_SECRET);
}

void Audio::play(Clip clip)
{
	Mix_Chunk *audio = clips[clip];

    if (audio == NULL)
    {
        // It shows a number, not a name. HELPFUL? NOT EXTREMELY.
        cerr << "Cannot play audio clip " << clip
            <<  " because it was not loaded into memory." << endl;
       return;
    }

    Mix_PlayChannel(-1, audio, 0);
}

void Audio::play(Song song)
{
    Mix_Music *audio = songs[song];

    if (audio == NULL)
    {
        // It shows a number, not a name. HELPFUL? NOT EXTREMELY.
        cerr << "Cannot play song " << song
            <<  " because it was not loaded into memory." << endl;
        return;
    }

    if (Mix_PlayMusic(audio, 0) == -1)
    {
        cerr << "Unable to play song " << song << ": " << Mix_GetError()
            << endl;
		return;
    }

}

void Audio::stopSong()
{
    Mix_PauseMusic();
}

bool Audio::load(const char *inFile, Clip clip)
{
    Mix_Chunk *audio = Mix_LoadWAV(inFile);

    if (audio == NULL)
    {
        cerr << "Could not load audio file " << inFile << ": "
            << SDL_GetError() << endl;
        return false;
    }

	clips.insert(std::pair<Clip, Mix_Chunk *> (clip, audio));
    return true;
}

bool Audio::load(const char *inFile, Song song)
{
    Mix_Music *audio = Mix_LoadMUS(inFile);

    if (audio == NULL)
    {
        cerr << "Could not load audio file " << inFile << " because "
            << SDL_GetError() << endl;
        return false;
    }

    songs.insert(std::pair<Song, Mix_Music *> (song, audio));
    return true;
}

void Audio::unload(Clip clip)
{
    Mix_Chunk *audio = clips[clip];

    if (audio == NULL)
    {
        return;
    }

    Mix_FreeChunk(audio);
    clips.erase(clip);
}

void Audio::unload(Song song)
{
    Mix_Music *audio = songs[song];

    if (audio == NULL)
    {
        return;
    }

    Mix_FreeMusic(audio);
    songs.erase(song);
}
